home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / sound / ym2413.c < prev    next >
C/C++ Source or Header  |  2000-04-23  |  9KB  |  312 lines

  1. /**************************************************************
  2.  
  3.   YM2413 Translator
  4.  
  5.   Written by Paul Leaman
  6.  
  7.   Translates YM2413 commands to YM3812 commands.
  8.  
  9.   The two chips are almost register compatible with the
  10.   following exceptions.
  11.  
  12.   1) The 2413 has a bank of pre-defined instruments.
  13.   2) The 2413 has extra volume registers for each voice.
  14.   3) The frequency is supplied as an "F-Number" and "Block".
  15.      The F-Number has a smaller range in the 2413
  16.  
  17.   There are 2 modes of operation:
  18.   - Melody mode with 9 simultaneous voices
  19.   - Rhythm mode with 6 melody sounds + 5 rhythm sounds
  20.  
  21. ***************************************************************/
  22.  
  23. #include "driver.h"
  24.  
  25.  
  26. #define ym2413_channels 9           /* 9 channels per chip */
  27. #define ym2413_parameter_count 12   /* Number of values per row in instrument table */
  28.  
  29. /* Status for each chip */
  30. typedef struct YM2413_state
  31. {
  32.     int rhythm_mode;                            /* Is this chip in rhythm mode */
  33.     int pending_register;                       /* Last address register value */
  34.     int user_instrument[ym2413_parameter_count];    /* User instrument values */
  35. }YM2413_state;
  36.  
  37. static struct YM2413_state ym2413_state[MAX_2413];
  38.  
  39. /*
  40. Built-in instrument table:
  41.     00=Original (user)      08=Organ
  42.     01=Violin               09=Horn
  43.     02=Guitar               10=Synthesizer
  44.     03=Piano                11=Harpsicord
  45.     04=Flute                12=Vibraphone
  46.     05=Clarinet             13=Synthesizer Bass
  47.     06=Oboe                 14=Acoustic bass
  48.     07=Trumpet              15=Electric Guitar
  49.  
  50. Rhythm sounds:
  51.     Bass Drum
  52.     Hihat
  53.     Snare
  54.     Tom-Tom
  55.     Top-Cymbal
  56.  
  57. If rhythm mode is enabled, the last three channels are used for rhythm output.
  58.  
  59. WS1, WS2 and FB aren't used at present.
  60.  
  61. */
  62.  
  63. int ym2413_instruments[0x13][ym2413_parameter_count]=
  64. {
  65.      /* AM1  AM2  KS1  KS2  AD1  AD2  SR1  SR2  WS1  WS2   FB */
  66.     {  0x21,0x01,0x72,0x04,0xf1,0x84,0x7e,0x6d,0x00,0x00,0x00 },    /* 00 User          */
  67.     {  0x01,0x22,0x23,0x07,0xf0,0xf0,0x07,0x18,0x00,0x00,0x00 },    /* 01 Violin        */
  68.     {  0x23,0x01,0x68,0x05,0xf2,0x74,0x6c,0x89,0x00,0x00,0x00 },    /* 02 Guitar        */
  69.     {  0x13,0x11,0x25,0x00,0xd2,0xb2,0xf4,0xf4,0x00,0x00,0x00 },    /* 03 Piano         */
  70.     {  0x22,0x21,0x1b,0x05,0xc0,0xa1,0x18,0x08,0x00,0x00,0x00 },    /* 04 Flute         */
  71.     {  0x22,0x21,0x2c,0x03,0xd2,0xa1,0x18,0x57,0x00,0x00,0x00 },    /* 05 Clarinet      */
  72.     {  0x01,0x22,0xba,0x01,0xf1,0xf1,0x1e,0x04,0x00,0x00,0x00 },    /* 06 Oboe          */
  73.     {  0x21,0x21,0x28,0x06,0xf1,0xf1,0x6b,0x3e,0x00,0x00,0x00 },    /* 07 Trumpet       */
  74.     {  0x27,0x21,0x60,0x00,0xf0,0xf0,0x0d,0x0f,0x00,0x00,0x00 },    /* 08 Organ         */
  75.     {  0x20,0x21,0x2b,0x06,0x85,0xf1,0x6d,0x89,0x00,0x00,0x00 },    /* 09 Horn          */
  76.     {  0x01,0x21,0xbf,0x02,0x53,0x62,0x5f,0xae,0x01,0x00,0x00 },    /* 10 Synthesizer   */
  77.     {  0x23,0x21,0x70,0x07,0xd4,0xa3,0x4e,0x64,0x01,0x00,0x00 },    /* 11 Harpsicode    */
  78.     {  0x2b,0x21,0xa4,0x07,0xf6,0x93,0x5c,0x4d,0x00,0x00,0x00 },    /* 12 Vibraphone    */
  79.     {  0x21,0x23,0xad,0x07,0x77,0xf1,0x18,0x37,0x00,0x00,0x00 },    /* 13 SynthBass     */
  80.     {  0x21,0x21,0x2a,0x03,0xf3,0xe2,0x29,0x46,0x00,0x00,0x00 },    /* 14 AcousticBass  */
  81.     {  0x21,0x23,0x37,0x03,0xf3,0xe2,0x29,0x46,0x00,0x00,0x00 },    /* 15 ElectricGuitar*/
  82.     /*
  83.     There are 5 rhythms using 3 channels. I'm not sure how this works.
  84.     I think that they may be shared, ie:
  85.         7=Bass drum
  86.         8=Hihat   / Snare drum
  87.         9=Tom-Tom / Top-Cymbal
  88.     */
  89.     {  0x13,0x11,0x25,0x00,0xd7,0xb7,0xf4,0xf4,0x00,0x00,0x00 },    /* 16 Rhythm 1: */
  90.     {  0x13,0x11,0x25,0x00,0xd7,0xb7,0xf4,0xf4,0x00,0x00,0x00 },    /* 17 Rhythm 2: */
  91.     {  0x13,0x11,0x25,0x00,0xd7,0xb7,0xf4,0xf4,0x00,0x00,0x00 },    /* 18 Rhythm 3: */
  92. };
  93.  
  94. INLINE void OPL_WRITE(int reg, int data)
  95. {
  96.     YM3812_control_port_0_w(0, reg);
  97.     YM3812_write_port_0_w(0, data);
  98. }
  99.  
  100. INLINE void OPL_WRITE_DATA1(int offset, int channel, int data)
  101. {
  102.     static const int order[ym2413_channels]={0x00,0x01,0x02,0x08,0x09,0x0a,0x10,0x11,0x12};
  103.     OPL_WRITE(offset+order[channel], data);
  104. }
  105.  
  106. INLINE void OPL_WRITE_DATA2(int offset, int channel, int data)
  107. {
  108.     static const int order[ym2413_channels]={0x03,0x04,0x05,0x0b,0x0c,0x0d,0x13,0x14,0x15};
  109.     OPL_WRITE(offset+order[channel], data);
  110. }
  111.  
  112. void ym2413_setinstrument(int chip, int channel, int inst)
  113. {
  114.     static const int reg[10]=
  115.     {
  116.         0x20,0x20,0x40,0x40,0x60,0x60,0x80,0x80,0xe0,0xe0
  117.     };
  118.     int *pn;
  119.     int i;
  120.  
  121.     if (!inst)
  122.     {
  123.         /* Take values from user instrument settings for this chip */
  124.         pn=&ym2413_state[chip].user_instrument[0];
  125.     }
  126.     else
  127.     {
  128.         /* Lift stored instrument values from instrument table */
  129.         pn=&(ym2413_instruments[inst][0]);
  130.     }
  131.  
  132.     for (i=0; i<10; i++)
  133.     {
  134.         if (i & 0x01)
  135.         {
  136.             OPL_WRITE_DATA2(reg[i], channel, *pn);
  137.         }
  138.         else
  139.         {
  140.             OPL_WRITE_DATA1(reg[i], channel, *pn);
  141.         }
  142.         pn++;
  143.     }
  144.  
  145.     /* I dont know wich connection type the YM2413 has */
  146.     /* So we leave feedback to the default for now */
  147.     /*    OPL_WRITE(0xc0+channel, ( (*pn) << 1 )); */
  148. }
  149.  
  150. int YM2413_sh_start(const struct MachineSound *msound)
  151. {
  152.     int i, j;
  153.     for (i=0; i<MAX_2413; i++)
  154.     {
  155.         /* Reset the chip state to 0 */
  156.         memset(&ym2413_state[i], 0, sizeof(ym2413_state[0]));
  157.  
  158.         /*
  159.         Copy default values for the user instument. This is not strictly necessary,
  160.         but will allow altering of the extra OPL settings that aren't
  161.         set by the 2413 (feedback and wave select).
  162.         */
  163.         for (j=0; j<ym2413_parameter_count; j++)
  164.         {
  165.             ym2413_state[i].user_instrument[j]=ym2413_instruments[0][j];
  166.         }
  167.     }
  168.     return YM3812_sh_start(msound);
  169. }
  170.  
  171. void YM2413_sh_stop(void)
  172. {
  173.     int i;
  174.     /* Clear down the OPL chip (emulated or real) */
  175.     for (i=0; i<0xf5; i++)
  176.     {
  177.         OPL_WRITE(i, 0);
  178.     }
  179.  
  180.     YM3812_sh_stop();
  181. }
  182.  
  183. READ_HANDLER( YM2413_status_port_0_r )
  184. {
  185.     return YM3812_status_port_0_r(offset);
  186. }
  187.  
  188. WRITE_HANDLER( YM2413_register_port_0_w )
  189. {
  190.     int chip = offset;
  191.     ym2413_state[chip].pending_register=data;
  192. }
  193.  
  194. WRITE_HANDLER( YM2413_data_port_0_w )
  195. {
  196.     int chip = offset;
  197.     int value, channel, instrument, i, block, volume;
  198.     int pending=ym2413_state[chip].pending_register;
  199.  
  200.     switch(pending)
  201.     {
  202.         case 0x00: /* YM2413 ADSR registers */
  203.         case 0x01:
  204.         case 0x02:
  205.         case 0x03:
  206.         case 0x04:
  207.         case 0x05:
  208.         case 0x06:
  209.         case 0x07:
  210.                 ym2413_state[chip].user_instrument[pending] = data;
  211.                 break;
  212.  
  213.         case 0x0e: /* Rhythm control */
  214.                 ym2413_state[chip].rhythm_mode=data&0x20;
  215.                 if (data & 0x20 )
  216.                 {
  217.                     /* We are entering rhythm control */
  218.                     for (i=6; i<9; i++)
  219.                     {
  220.                         /* Turn off key select */
  221.                         OPL_WRITE(0xb0+i, 0);
  222.                     }
  223.                     ym2413_setinstrument(chip, 6, 16);  /* Rhythmn 1 */
  224.                     ym2413_setinstrument(chip, 7, 17);  /* Rhythmn 2 */
  225.                     ym2413_setinstrument(chip, 8, 18);  /* Rhythmn 3 */
  226.                 }
  227.  
  228.                 OPL_WRITE(0xbd, data & 0x3f);
  229.                 break;
  230.  
  231.         case 0x10: /* F-Number 8 bits */
  232.         case 0x11:
  233.         case 0x12:
  234.         case 0x13:
  235.         case 0x14:
  236.         case 0x15:
  237.         case 0x16:
  238.         case 0x17:
  239.         case 0x18:
  240.                 channel=pending-0x10;
  241.                 OPL_WRITE(0xa0+channel, data);  /* Frequency LSB */
  242.                 break;
  243.  
  244.         case 0x20:  /* FNumber / note on / off */
  245.         case 0x21:
  246.         case 0x22:
  247.         case 0x23:
  248.         case 0x24:
  249.         case 0x25:
  250.         case 0x26:
  251.         case 0x27:
  252.         case 0x28:
  253.                 channel=pending-0x20;
  254.                 block=(data>>1)&0x07;
  255.                 value = ( data & 0x10) << 1;  /* Translate key on-off */
  256.                 /* Sustain does not exist */
  257.                 value |= data&0x01;           /* Add freq MSB */
  258.                 value |= (block<<2);          /* Add in octave */
  259.                 OPL_WRITE(0xb0+channel, value); /* Frequency MSB + Key on/off */
  260.                 break;
  261.  
  262.         case 0x30: /* INSTRUMENT / VOLUME */
  263.         case 0x31:
  264.         case 0x32:
  265.         case 0x33:
  266.         case 0x34:
  267.         case 0x35:
  268.         case 0x36:
  269.         case 0x37:
  270.         case 0x38:
  271.                 channel=pending-0x30;
  272.  
  273.                 if (ym2413_state[chip].rhythm_mode && channel >= 6)
  274.                 {
  275.                     /*
  276.                     Running in rhythm mode. 6, 7 and 8 contain the volumes
  277.                     of the rhythm voices encoded in the hi/low nibbles
  278.                     of the control byte.
  279.  
  280.                         0x06 = <NONE>              | BASS DRUM LEVEL   0-15
  281.                         0x07 = HIHAT LEVEL   0-15  | SNARE DRUM LEVEL  0-15
  282.                         0x08 = TOM-TOM LEVEL 0-15  | TOP-CYMBAL LEVEL  0-15
  283.                     */
  284.  
  285.                     /*
  286.                     TODO: I don't know how to alter the volume of the individual
  287.                     rhythm voices since they share channels on the OPL.
  288.                     */
  289.                 }
  290.                 else
  291.                 {
  292.                     /* Write instrument data */
  293.                     instrument=(data >> 4) & 0x0f;
  294.                     ym2413_setinstrument(chip, channel, instrument);
  295.  
  296.                     /* Set the voice volume (0-15) */
  297.                     volume=data & 0x0f;
  298.  
  299.                     /*
  300.                     TODO: I don't know how to alter the volume for each voice
  301.                     */
  302.                 }
  303.                 break;
  304.  
  305.         default:
  306.                 logerror("YM2413: Write to register %02x\n", pending);
  307.                 break;
  308.     }
  309. }
  310.  
  311.  
  312.